const { minioClient, bucketName } = require('@root/config/minio');
const { poolPromise } = require('@root/db/index');
const { validationResult } = require('express-validator');
const { validateParams } = require('@root/utils/peak-tools.js');
const { httpStatusCode } = require('@root/types/HttpStatusCode');
const uuid = require('uuid');
const multer = require('multer');

const storage = multer.memoryStorage(); // 配置 Multer 内存存储
const upload = multer({ storage });


/**
 * 上传文件
 * @param {*} req
 * @param {*} res
 */
const uploadFile = async (req, res, next) => {
  try {
    /**
     * // OPTIMIZE: 优化点
     *  1 : 获取文件hash
     *  2 : 校验是否上传
     *  3 : 已上传就直接查出返回
     *  4 : 未上传就上传
     *  5 : 写入文件信息
     */
    const file = req.file;
    if (!req.file) {
      return res.status(httpStatusCode.BadRequest).json({
        code: httpStatusCode.BadRequest,
        msg: 'file参数不能为空',
        data: null,
      });
    }

    const fileId = uuid.v4();
    const fileHash = uuid.v4();
    const originalname = file.originalname;
    // const fileSuffix = path.extname(originalname);
    const fileName = `${fileHash}${originalname}`;
    const fileType = file.mimetype;
    const now = new Date();
    const date = `${now.getFullYear()}-${String(now.getMonth() + 1).padStart(2, '0')}-${String(now.getDate()).padStart(2, '0')}`
    const filePath = `/${date}/${fileName}`;   // 可以使用文件夹结构来组织文件
    // const fileUrl = `http://8.153.103.127:9000/${bucketName}${filePath}`
    const fileUrl = `/${bucketName}${filePath}`

    // 上传到 MinIO
    await minioClient.putObject(
      bucketName,
      filePath,   // fileName,
      file.buffer,
      file.size,
      {
        'Content-Type': file.mimetype,
        'X-File-Id': fileHash // 可以在元数据中存储文件ID
      }
    );

    const file_insert_sql = `insert into file_resources (file_id, file_hash, originalname, file_name, file_size,file_url, file_path, file_type) values (?, ?, ?, ?, ?, ?, ?, ?)`;
    // 存储数据到 MySQL
    await poolPromise.execute(
      file_insert_sql,
      [
        fileId,
        fileHash,
        originalname,
        fileName,
        file.size,
        fileUrl,
        filePath,
        fileType
      ]
    );

    const file_select_sql = `select * from file_resources where file_hash = ?`;
    const [file_result] = await poolPromise.execute(
      file_select_sql,
      [
        fileHash
      ]
    );
    res.status(httpStatusCode.Ok).json({
      code: httpStatusCode.Ok,
      msg: '文件上传成功',
      fileInfo: {
        ...file_result[0],
        file_url: fileUrl
      }
    });
  } catch (err) {
    next(err)
  }
};

/**
 * 获取文件列表
 * @param {*} req
 * @param {*} res
 */
const getFiles = async (req, res, next) => {
  try {
    // 分页参数
    const { currentPage = 1, pageSize = 10, fileName = null } = req.query
    const select_file_sql = `select * from file_resources where file_name like concat('%', ?, '%') limit ?,?`
    const [files] = await poolPromise.execute(select_file_sql, [
      fileName,
      ((currentPage - 1) * pageSize).toString(),
      pageSize
    ]);
    res.status(httpStatusCode.Ok).json({
      code: httpStatusCode.Ok,
      msg: '文件列表获取成功',
      data: files.map(item => {
        return {
          ...item,
        }
      })
    });
  } catch (err) {
    next(err);
  }
};

/**
 * 下载文件
 */
const downloadFile = async (req, res, next) => {
  try {
    const { id } = req.params;
    const [rows] = await poolPromise.execute('SELECT * FROM file_resources WHERE file_id = ?', [id]);
    if (!rows.length) return res.status(httpStatusCode.NotFound).json({
      code: httpStatusCode.NotFound,
      msg: '没有该文件'
    });

    const file = rows[0];
    const stream = await minioClient.getObject(bucketName, file.file_path);
    res.header('Content-Type', file.file_type);
    res.header('Content-Disposition', `attachment; filename="${encodeURIComponent(file.file_name)}"`);
    stream.pipe(res); // 将文件流发送到客户端
  } catch (err) {
    next(err)
  }
};

/**
 * 删除文件
 */
const deleteFile = async (req, res, next) => {
  if (validateParams({ req, res, validationResult })) return;
  try {
    const { ids } = req.body;
    const [a, , b] = [1, 2, 3]
    console.log(a, b);

    const placeholders = new Array(ids.length)
      .fill('?')
      .join(',')
    const select_file_sql = `select * from file_resources where file_id in (${placeholders});`
    const [rows] = await poolPromise.execute(select_file_sql, ids);


    if (!rows.length) return res.status(404).json({ error: 'File not found' });

    rows.forEach((item) => {
      // 从 MinIO 删除
      minioClient.removeObject(bucketName, item.file_path);
    });

    // 从数据库删除
    await poolPromise.execute(`DELETE FROM file_resources WHERE file_id in (${placeholders})`, ids);

    res.status(httpStatusCode.Ok).json({
      code: httpStatusCode.Ok,
      msg: '文件删除成功'
    });
  } catch (err) {
    next(err);
  }
};

module.exports = {
  uploadFile,
  getFiles,
  downloadFile,
  deleteFile,
  uploadMiddleware: upload.single('file')
};